<?php

/**
 * CCoreMimeParameter
 * CCoreMimeParametersCollection
 *
 * @author Usenko Timur <usenko.timur@gmail.com>
 * @package mime
 */

CCore::Using('base.collection');

/**
 * @package mime
 */
class CCoreMimeParameter
{
	#<editor-fold defaultstate="collapsed" desc="private">
	/**
	 * @var string
	 */
	private $_sName;

	/**
	 * @var string
	 */
	private $_sValue;
	#</editor-fold>

	/**
	 * @param string $sName = ''
	 * @param string $sValue = ''
	 * @return CCoreMimeParameter
	 */
	public function __construct($sName = '', $sValue = '')
	{
		CCore::CheckTypes(array('$sName', '$sValue'));
		
		$this->_sName = $sName;
		$this->_sValue = $sValue;
	}

	/**
	 * @return void
	 */
	public function Reset()
	{
		$this->_sName = '';
		$this->_sValue = '';
	}
	
	/**
	 * @return string
	 */
	public function Name()
	{
		return $this->_sName;
	}

	/**
	 * @return string
	 */
	public function Value()
	{
		return $this->_sValue;
	}

	/**
	 * @param string $sRawParam
	 * @param string $sSeparator = '='
	 * @return void
	 */
	public function Parse($sRawParam, $sSeparator = '=')
	{
		CCore::CheckTypes(array('$sRawParam', '$sSeparator'));

		$this->Reset();

		$aParts = explode($sSeparator, $sRawParam, 2);

		$this->_sName = trim(trim($aParts[0]), '"\'');
		if (2 === count($aParts))
		{
			$this->_sValue = trim(trim($aParts[1]), '"\'');
		}
	}
}

/**
 * @package mime
 */
class CCoreMimeParametersCollection extends ACoreBaseCollection
{
	/**
	 * @param string $nsRawParams = null
	 * @return CCoreMimeParametersCollection
	 */
	public function __construct($nsRawParams = null)
	{
		CCore::CheckTypes(array('$nsRawParams'));
		
		parent::__construct();

		if (null !== $nsRawParams)
		{
			$this->_parse($nsRawParams);
		}
	}

	/**
	 * @param string $sName
	 * @return string
	 */
	public function GetParamValueByName($sName)
	{
		CCore::CheckTypes(array('$sName'));

		$aParams =& $this->GetAsArray();
		foreach ($aParams as /* @var $oParam CCoreMimeParameter */ $oParam)
		{
			if (strtolower($sName) === strtolower(trim($oParam->Name())))
			{
				return $oParam->Value();
			}
		}
		return '';
	}

	/**
	 * @param CCoreMimeParameter $oMimeParameter
	 * @return void
	 */
	public function Add(CCoreMimeParameter $oMimeParameter)
	{
		CCore::CheckTypes(array('$oMimeParameter'));

		parent::Add($oMimeParameter);
	}
	
	/**
	 * @param string $sDataToParse
	 * @return void
	 */
	private function _parse($sDataToParse)
	{
		CCore::CheckTypes(array('$sDataToParse'));
		
		$aDataToParse = explode(';', $sDataToParse);

		foreach ($aDataToParse as $sParam)
		{
			$oMimeParameter = new CCoreMimeParameter();
			$oMimeParameter->Parse($sParam);
			$this->Add($oMimeParameter);
			unset($oMimeParameter, $sParam);
		}

		$this->_reParseParameters();
	}

	/**
	 * @return void
	 */
	private function _reParseParameters()
	{
		$aDataToReParse = $this->CloneAsArray();

		$this->Clear();
		$aPreParams = array();
		foreach ($aDataToReParse as /* @var $oParam CCoreMimeParameter */ $oParam)
		{
			$aMatch = array();
			$sParamName = $oParam->Name();
			if (preg_match('/([^\*]+)\*([\d]{1,2})\*/', $sParamName, $aMatch) && isset($aMatch[1], $aMatch[2])
				&& 0 < strlen($aMatch[1]) && is_numeric($aMatch[2]))
			{
				if (!isset($aPreParams[$aMatch[1]]))
				{
					$aPreParams[$aMatch[1]] = array();
				}
				
				$aPreParams[$aMatch[1]][(int) $aMatch[2]] = $oParam->Value();
			}
			else
			{
				$this->Add($oParam);
			}
		}

		foreach ($aPreParams as $sName => $aValues)
		{
			ksort($aValues);
			$oMimeParameter = new CCoreMimeParameter($sName, implode($aValues));
			$this->Add($oMimeParameter);
			unset($oMimeParameter);
		}
	}
}
